package com.cskaoyan.service;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.common.BasePageInfo;
import com.cskaoyan.bean.common.CommonData;
import com.cskaoyan.bean.vo.admin.role.permissions.ChildType;
import com.cskaoyan.bean.vo.admin.role.permissions.ParentType;
import com.cskaoyan.bean.vo.admin.role.permissions.ParentType2;
import com.cskaoyan.mapper.MarketPermissionMapper;
import com.cskaoyan.mapper.MarketPermissionTypeMapper;
import com.cskaoyan.mapper.MarketRoleMapper;
import com.cskaoyan.utils.StringUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @Author: JianhuaZeng
 * @Date: 2022/12/29 20:52
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    MarketRoleMapper roleMapper;

    @Autowired
    MarketPermissionMapper permissionMapper;

    @Autowired
    MarketPermissionTypeMapper permissionTypeMapper;

    @Autowired
    AdminService adminService;

    public List<MarketRole> allRole() {
        MarketRoleExample roleExample = new MarketRoleExample();
        MarketRoleExample.Criteria criteria = roleExample.createCriteria();
        criteria.andEnabledEqualTo(true);
        criteria.andDeletedEqualTo(false);
        List<MarketRole> roles = roleMapper.selectByExample(roleExample);
        return roles;
    }

    /**
     * @description: 插入数据并返回自增主键id
     * @param: marketRole
     * @return: java.lang.Integer
     * @author: JianhuaZeng
     * @date: 2022/12/29 2022/12/29
     */
    public Integer createRole(MarketRole marketRole) {
        roleMapper.insertSelective(marketRole);
        return marketRole.getId();
    }

    /**
     * @description: 进行分页查询、排序和模糊匹配
     * @param: pageInfo
     * @return: com.cskaoyan.bean.common.CommonData<com.cskaoyan.bean.MarketRole>
     * @author: JianhuaZeng
     * @date: 2022/12/29 2022/12/29
     */
    public CommonData<MarketRole> list(BasePageInfo pageInfo) {
        PageHelper.startPage(pageInfo.getPage(), pageInfo.getLimit());
        MarketRoleExample roleExample = new MarketRoleExample();
        MarketRoleExample.Criteria criteria = roleExample.createCriteria();
        criteria.andEnabledEqualTo(true);
        criteria.andDeletedEqualTo(false);
        if (!StringUtil.isEmpty(pageInfo.getName())) {
            // 根据name进行模糊查询
            criteria.andNameLike("%" + pageInfo.getName() + "%");
        }
        // 排序
        roleExample.setOrderByClause(pageInfo.getSort() + " " + pageInfo.getOrder());
        List<MarketRole> roles = roleMapper.selectByExample(roleExample);
        PageInfo<MarketRole> rolePageInfo = new PageInfo<>(roles);

        // 构造返回对象
        CommonData<MarketRole> data = CommonData.data(rolePageInfo);
        return data;
    }

    /**
     * @description: 根据id修改role的信息
     * @param: marketRole
     * @return: void
     * @author: JianhuaZeng
     * @date: 2022/12/30 2022/12/30
     */
    public void update(MarketRole marketRole){
        roleMapper.updateByPrimaryKeySelective(marketRole);
    }

    /**
     * @description: 逻辑删除role
     * @param: marketRole
     * @return: int 0:当前角色存在管理员，不能删除 1:逻辑删除成功
     * @author: JianhuaZeng
     * @date: 2022/12/30 2022/12/30
     */
    public int delete(MarketRole marketRole){
        Integer id = marketRole.getId();
        List<MarketAdmin> admins = adminService.allAdmins();
        for (MarketAdmin admin : admins) {
            if(Arrays.asList(admin.getRoleIds()).contains(id)){
                // 当前角色存在管理员，不能删除
                return 0;
            }
        }
        // 执行逻辑删除
        MarketRole role = new MarketRole();
        role.setId(id);
        role.setDeleted(true);
        roleMapper.updateByPrimaryKeySelective(role);
        return 1;
    }

    /**
     * @description: 根据roleId查询对应的权限
     * @param: roleId
     * @return: java.util.List<java.lang.String>
     * @author: JianhuaZeng
     * @date: 2022/12/30 2022/12/30
     */
    public List<String> getRolePermissions(int roleId){
        MarketPermissionExample permissionExample = new MarketPermissionExample();
        MarketPermissionExample.Criteria criteria = permissionExample.createCriteria();
        criteria.andDeletedEqualTo(false);
        criteria.andRoleIdEqualTo(roleId);
        List<MarketPermission> permissions = permissionMapper.selectByExample(permissionExample);
        List<String> listPer = new ArrayList<>();
        permissions.forEach(marketPermission -> listPer.add(marketPermission.getPermission()));
        return listPer;
    }

    /**
     * @description: 查询所有的权限，包括对应的子权限
     * @return: java.util.List<com.cskaoyan.bean.vo.admin.role.permissions.ParentType>
     * @author: JianhuaZeng
     * @date: 2022/12/30 2022/12/30
     */
    public List<ParentType> getSysPermissions(){
        // 查询所有一级权限
        List<MarketPermissionType> parentTypes = getSysPermissionsByTypeAndPid(1, null);
        // 创建list用来存放查询到的一级权限
        List<ParentType> parentTypeList = new ArrayList<ParentType>();
        for (MarketPermissionType parentType : parentTypes) {
            // 查询一级权限对应的二级权限
            List<MarketPermissionType> parentTypes2 = getSysPermissionsByTypeAndPid(2,
                    parentType.getId());
            // 创建list用来存放查询到的二级权限
            List<ParentType2> parentType2List = new ArrayList<>();
            for (MarketPermissionType parentType2 : parentTypes2) {
                // 查询二级权限对应的三级权限
                List<MarketPermissionType> childTypes = getSysPermissionsByTypeAndPid(3,
                        parentType2.getId());
                // 创建list用来存放查询到的三级权限
                List<ChildType> childTypeList = new ArrayList<>();
                for (MarketPermissionType childType : childTypes) {
                    childTypeList.add(new ChildType(childType.getName(),childType.getLabel(),childType.getApi()));
                }
                parentType2List.add(new ParentType2(parentType2.getLabel(),parentType2.getLabel(),childTypeList));
            }
            parentTypeList.add(new ParentType(parentType.getLabel(),parentType.getLabel(),parentType2List));
        }
        return parentTypeList;
    }

    /**
     * @description: 根据type和pid查询
     * @param: type
     * @param: pid
     * @return: java.util.List<com.cskaoyan.bean.MarketPermissionType>
     * @author: JianhuaZeng
     * @date: 2022/12/30 2022/12/30
     */
    public List<MarketPermissionType> getSysPermissionsByTypeAndPid(int type,Integer pid){
        MarketPermissionTypeExample typeExample = new MarketPermissionTypeExample();
        MarketPermissionTypeExample.Criteria criteria = typeExample.createCriteria();
        criteria.andTypeEqualTo(type);
        if (pid != null){
            criteria.andPidEqualTo(pid);
        }
        return permissionTypeMapper.selectByExample(typeExample);
    }

    /**
     * @description: 更新role的权限列表
     * @param: roleId
     * @param: permissions
     * @return: void
     * @author: JianhuaZeng
     * @date: 2022/12/30 2022/12/30
     */
    public void updatePermissionByRoleId(int roleId, List<String> permissions){
        Date date = new Date();
        // 先逻辑删除role原有的权限
        MarketPermissionExample permissionExample = new MarketPermissionExample();
        MarketPermissionExample.Criteria criteria = permissionExample.createCriteria();
        // 筛选出要逻辑删除的记录
        criteria.andRoleIdEqualTo(roleId);
        criteria.andDeletedEqualTo(false);
        // 逻辑删除的记录需要更新的内容
        MarketPermission record = new MarketPermission();
        record.setDeleted(true);
        record.setUpdateTime(date);
        permissionMapper.updateByExampleSelective(record,permissionExample);

        // 增加role的权限
        for (String perm : permissions) {
            MarketPermission insert = new MarketPermission();
            insert.setRoleId(roleId);
            insert.setPermission(perm);
            insert.setAddTime(date);
            insert.setUpdateTime(date);
            insert.setDeleted(false);
            permissionMapper.insertSelective(insert);
        }
    }
}
